package com.ins1st.plugins;

import com.ins1st.http.HttpContext;
import com.ins1st.util.DatabaseUtil;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.plugin.*;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.reflection.SystemMetaObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.sql.Connection;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.TreeMap;

/**
 * @program: ins1st-cloud
 * @description:
 * @author: coderSun
 * @create: 2019-11-23 12:39
 **/
@Component
@Intercepts({@Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class, Integer.class})})
public class MybatisInterceptor implements Interceptor {

    private static final Logger log = LoggerFactory.getLogger(MybatisInterceptor.class);

    private Map<String, List<String>> tableCache = new TreeMap<>();

    @Autowired
    DatabaseUtil databaseUtil;

    @Override
    public Object plugin(Object target) {

        return Plugin.wrap(target, this);
    }

    @Override
    public void setProperties(Properties properties) {
        System.out.println("1");
    }

    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        HttpServletRequest request = HttpContext.getRequest();
        StatementHandler statementHandler = (StatementHandler) invocation.getTarget();
        MetaObject metaStatementHandler = SystemMetaObject.forObject(statementHandler);
        String sql = String.valueOf(metaStatementHandler.getValue("delegate.boundSql.sql"));
        String tenantId = request.getHeader("tenant_id");
        log.debug("当前租户id: {}",tenantId);
        if (StringUtils.isNotBlank(tenantId)) {
            if (!tableCache.containsKey(tenantId)) {
                tableCache.put(tenantId, databaseUtil.getTableNames());
            }
            for (String tableName : tableCache.get(tenantId)) {
                if (sql.contains(tableName)) {
                    if (!sql.substring(sql.indexOf(tableName) - 1, sql.indexOf(tableName)).equals(".")) {
                        sql = sql.replace(tableName, "ins1st_" + tenantId + "." + tableName);
                    }
                }
            }
            metaStatementHandler.setValue("delegate.boundSql.sql", sql);
        }
        return invocation.proceed();
    }


}
